package com.shop.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.entity.dto.AdminUser.*;
import com.shop.entity.pojo.AdminUser;
import com.shop.admin.mapper.AdminUserMapper;
import com.shop.admin.service.AdminUserService;
import com.shop.utils.common.enums.Code;
import com.shop.utils.common.enums.Jwt;
import com.shop.utils.common.enums.Message;
import com.shop.utils.common.result.PageResponseResult;
import com.shop.utils.common.result.Result;
import com.shop.utils.config.BaseContext;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service

public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements AdminUserService {

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Override
    public Result<String> login(AdminUserLoginDto dto) {
        if (dto==null) {
            return Result.errorResult(Code.PARAM_REQUIRE);
        }
        AdminUser login = adminUserMapper.selectOne(Wrappers.<AdminUser>lambdaQuery()
                .eq(AdminUser::getName,dto.getAdminName()).or()
                .eq(AdminUser::getPhone,dto.getAdminName()));
        String password=DigestUtils.md5Hex(login.getSalt()+dto.getPassword());
        AdminUser adminUser = adminUserMapper.selectOne(Wrappers.<AdminUser>lambdaQuery()
                .eq(AdminUser::getName,login.getName())
                .eq(AdminUser::getPassword,password));
        if (adminUser==null) {
            return Result.errorResult(Code.LOGIN_PASSWORD_ERROR);
        }
        String token = Jwts.builder()
                .setHeaderParam(Message.Jwt_Typ, Jwt.Admin_Jwt_Key.getTyp())
                .setHeaderParam(Message.Jwt_Alg,Jwt.Admin_Jwt_Key.getAlg())
                .setSubject(Jwt.Admin_Jwt_Key.getName())
                .setExpiration(new Date(System.currentTimeMillis()+Jwt.Admin_Jwt_Key.getExp()))
                .claim(Message.Admin_Id,adminUser.getId())
                .signWith(SignatureAlgorithm.HS256,Jwt.Admin_Jwt_Key.getKey())
                .compact();
        return Result.okResult(token);
    }

    @Override
    public Result<AdminUser> add(AdminUserSaveDto dto) {
        if (dto==null) {
            return Result.errorResult(Code.PARAM_REQUIRE);
        }
        Long adminId = BaseContext.getCurrentId();
        AdminUser adminUsers = adminUserMapper.selectOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId,adminId));
        if (adminUsers==null) {
            return Result.errorResult(Code.NEED_LOGIN);
        }
        AdminUser check = adminUserMapper.selectOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getPhone,dto.getPhone()));
        if (check!=null) {
            return Result.errorResult(Code.DATA_EXIST);
        }
        Random rm = new Random();
        double random = (1 + rm.nextDouble()) * Math.pow(10, 11);
        String name = String.valueOf(random);
        String newPW=adminUsers.getName()+dto.getPassword();
        newPW= DigestUtils.md5Hex(newPW);
        AdminUser admin=new AdminUser();
        admin= admin.builder()
                .name(name)
                .password(newPW)
                .oldPW(dto.getPassword())
                .phone(dto.getPhone())
                .salt(adminUsers.getName())
                .nickName(dto.getNickName())
                .saveAdmin(adminUsers.getName())
                .saveTime(String.valueOf(LocalDateTime.now())).build();
        int insert = adminUserMapper.insert(admin);
        if (insert==Message.Check_Int_False) {
            return Result.errorResult(Code.SERVER_ERROR);
        }
        return Result.okResult(Code.SUCCESS);
    }
    @Override
    public Result getAdminUserList(AdminUserListDto dto) {
        dto.checkParam();
        Page<AdminUser> page=new Page(dto.getPage(),dto.getSize());
        Page<AdminUser> value = adminUserMapper.getAllByPage(page, dto);
        Result result=new PageResponseResult(dto.getPage(),dto.getSize(), (int) value.getTotal());
        result.setData(value.getRecords());
        return result;
    }

    @Override
    public Result removeAdminUser(AdminUserRemoveDto dto) {
        if (dto==null) {
            return Result.errorResult(Code.PARAM_REQUIRE);
        }
        Long adminId = BaseContext.getCurrentId();
        AdminUser adminUser = adminUserMapper.selectById(adminId);
        if (adminUser==null||adminId==null) {
            return Result.errorResult(Code.DATA_NOT_EXIST);
        }
        AdminUser updAdminUser=new AdminUser();
        updAdminUser.setRemoveAdmin(adminUser.getName());
        if (dto.getRemoveMemo()!=null) {
            updAdminUser.setRemoveMemo(dto.getRemoveMemo());
        }
        int update = adminUserMapper.update(updAdminUser, Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, dto.getUserId()));
        int remove = adminUserMapper.deleteById(dto.getUserId());
        if (remove==Message.Check_Int_False||update==Message.Check_Int_False) {
            return Result.errorResult(Code.SERVER_ERROR);
        }

        return Result.okResult(Code.SUCCESS);
    }

    @Override
    public Result<Map<String,Object>> updateGetAdminUser(AdminUserUpdateForGetDto dto) {
        if (dto==null) {
            return Result.errorResult(Code.PARAM_REQUIRE);
        }
        AdminUser adminUser = adminUserMapper.selectById(dto.getUserId());
        if (adminUser==null) {
            return Result.errorResult(Code.DATA_NOT_EXIST);
        }
        Map<String,Object> map=new HashMap<>();
        map.put("nick",adminUser.getNickName());
        map.put("password",adminUser.getOldPW());
        return Result.okResult(map);
    }

    @Override
    public Result<Map<String, Object>> updateAdminUser(AdminUserUpdateDto dto) {
        if (dto==null) {
            return Result.errorResult(Code.PARAM_REQUIRE);
        }
        Long adminId = BaseContext.getCurrentId();
        AdminUser check = adminUserMapper.selectById(dto.getUserId());
        AdminUser checkToken = adminUserMapper.selectById(adminId);
        if (check==null||checkToken==null||adminId==null||dto.getUserId()!=adminId) {
            return Result.errorResult(Code.DATA_NOT_EXIST);
        }
        String nick=check.getNickName();
        String password=check.getOldPW();
        if (dto.getNick()!=null) {
            nick=dto.getNick();
        }
        if (dto.getPassword()!=null){
            password=dto.getPassword();
        }
        String newPW=check.getSalt()+password;
        String updatePassWord = DigestUtils.md5Hex(newPW);
        AdminUser adminUser=new AdminUser();
        adminUser= adminUser.builder()
                .nickName(nick)
                .oldPW(password)
                .password(updatePassWord)
                .saveTime(String.valueOf(LocalDateTime.now())).build();
        int update = adminUserMapper.update(adminUser, Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, dto.getUserId()));
        if (update==Message.Check_Int_False) {
            return Result.errorResult(Code.SERVER_ERROR);
        }
        return Result.okResult(Code.SUCCESS);
    }
}
